<?php

namespace handle\message\lib\traits;


use Exception;
use handle\message\lib\driver\lib\Event;
use handle\message\lib\manage\backups\Backups;
use handle\message\lib\manage\lib\ChessBoard;
use handle\message\lib\manage\lib\Player;
use handle\message\lib\manage\lib\Room;
use handle\message\lib\manage\PlayerManage;

trait ManageObserver
{
    use ManageSingleton;

    /**
     * 备份器
     * @var Backups
     */
    private Backups $backups;
    /**
     * 观察器
     * @var array
     */
    private array $observer = [];

    /**
     * 获取观察者信息
     * @param string $key
     * @return Room|ChessBoard|Event|array
     * @throws Exception
     */
    public function get(string $key)
    {
        workerLog('/get_manage', '使用了管理器[' . get_class($this) . ']' . PHP_EOL .  '获取观察者信息[' . $key . ']' . PHP_EOL .  '当前观察者信息[' . json_encode($this->observer) . ']');
        if(empty($this->observer[$key])){
            throw new Exception('房间已经解散');
        }
        return $this->observer[$key];
    }

    /**
     * 观察者是否存在
     * @param string $key
     * @return bool
     */
    public function isObserverIsset(string $key): bool
    {
        return isset($this->observer[$key]) and !empty($this->observer[$key]);
    }

//    private function makeObserverLog(){
//        $log = [
//            '管理器' => get_class($this),
//            '获取的观察者' => $key,
//            '所有观察者' => '',
//        ];
//
//        if(!empty($this->observer)){
//            foreach($this->observer as $v){
//                $log['所有观察者'] = $v
//            }
//        }
//
//    }

    /**
     * 获取玩家Player
     * @param string $room_id
     * @param int $uid
     * @return Player
     * @throws Exception
     */
    public function getPlayer(string $room_id, int $uid): Player
    {
        if(!(isset($this->observer[$room_id]) and !empty($this->observer[$room_id]) and isset($this->observer[$room_id][$uid]) and !empty($this->observer[$room_id][$uid]))){
            throw new Exception('玩家已经离开房间');
        }
        return $this->observer[$room_id][$uid];
    }

    /**
     * 玩家是否存在
     * @param string $room_id
     * @param int $uid
     * @return bool
     */
    public function isPlayerIsset(string $room_id, int $uid): bool
    {
        return (isset($this->observer[$room_id][$uid]) and !empty($this->observer[$room_id][$uid]));
    }

    /**
     * 删除观察者
     * @param string $key
     * @param int $uid
     * @return void
     */
    public function del(string $key, int $uid = 0){
        if(isset($this->observer[$key])){
            if($this instanceof PlayerManage and $uid > 0){
                unset($this->observer[$key][$uid]);
                return;
            }
            if($uid == 0 or empty($this->observer[$key]))unset($this->observer[$key]);
        }
    }

    /**
     * 更新观察者信息
     * @param string $room_id
     * @param Room|Player|ChessBoard|array $instance
     * @return void
     */
    public function update(string $room_id, $instance){
        if(is_array($instance)){
            [$uid, $values] = $instance;
            $this->observer[$room_id][$uid] = $values;
        }else{
            $this->observer[$room_id] = $instance;
        }
        $this->backups->setRoomID($room_id)->save($this);
    }

    /**
     * 重置
     * @param string $room_id
     * @return void
     * @throws Exception
     */
//    public function reset(string $room_id){
//        if($this instanceof PlayerManage){
//            foreach($this->get($room_id) as $player){
//                $player->init();
//            }
//        }else{
//            $this->observer[$room_id]->init();
//        }
//    }

    /**
     * 初始化
     * @return void
     */
    protected function initialization(){
        $this->backups = new Backups(); //创建备份类
    }

}